/*
 * Licensed this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.boapi.shop;

import org.boapi.core.IChecknumber;

/**
 * International Standard Book Number [ISBN] is a 13 digit number since 01.01.2007. Before 01.01.2007
 * the ISBN has 10 digits.
 * @author Sebastian Ritter
 * @version 3.0.0.0
 */
public abstract class ISBN implements IChecknumber {

	/**
	 * Create an old ISBN from new ISBN
	 * @param isbn13
	 * @return ISBN10
	 */
    public static ISBN10 parse (ISBN13 isbn13) {
      ISBN10 isbn = new ISBN10 ();
      isbn.setCompleteValue (new String[]{isbn13.getNumber ().substring(3,13)});
      isbn.setCompleteValue (new String[]{isbn.getNumber ().substring (0, 9) + isbn.getChecknumber ()});
      return isbn;
    }
    /** 
     * Create a new ISBN from GTIN code
     * @param gtin
     * @return ISBN13
     */
    public static ISBN13 parse (GTIN gtin) {
      ISBN13 isbn = new ISBN13 ();
      isbn.setCompleteValue (new String[] {gtin.getNumber ()});
      return isbn;
    }
    /**
     * The check digit
     */
    private char checknumber = 'R';
    /** 
     * Get the check digit
     * @return checknumber
     */
    protected char getChecknumber () {
      if ('R' == this.checknumber) {
        this.isChecknumberCorrect ();
      }
      return this.checknumber;
    }
    /**
     * Set the check digit
     * @param digit
     */
    protected void setChecknumber (char digit) {
      this.checknumber = digit;
    }
    /**
     * International Standard Book Number
     */
    private String number;
    /** 
     * Set the ISBN
     * @param isbn
     */
    public void setCompleteValue (String[] isbn) {
      StringBuilder nummer = new StringBuilder ();
      for (char c : isbn[0].toUpperCase().toCharArray ()) {
        if (Character.isDigit (c) || c == 'X') {
          nummer.append (c);
        }
        else if (c != '-') {
          throw new IllegalArgumentException ("Illegal character in ISBN "+ isbn[0]);
        }
      }
      this.setNumber(nummer.toString ());
      this.setChecknumber ('R');
    }
    /*
     * Same use as param keyword under C#
     */
    public void setCompleteValue (String isbn) {
    	this.setCompleteValue(new String[]{isbn});
    }

    
    /**
     *  The number of ISBN
     * @return String
     */
    public String getNumber () {
      return this.number;
    }
    /**
     * Set the ISBN number
     * @param number
     */
    protected void setNumber (String number) {
      this.number = number;
    }
    /**
     * Is the checknumber correct
     * @return boolean
     */
    public abstract boolean isChecknumberCorrect ();
  }

